import { ref, computed } from 'vue'

interface CacheItem<T> {
  data: T
  timestamp: number
  expiry?: number
}

interface CacheOptions {
  maxSize?: number
  defaultTTL?: number // Time to live in milliseconds
}

export function useCache<T>(options: CacheOptions = {}) {
  const { maxSize = 100, defaultTTL = 5 * 60 * 1000 } = options // 默认5分钟过期
  
  const cache = ref(new Map<string, CacheItem<T>>())
  
  // 设置缓存
  const set = (key: string, data: T, ttl?: number) => {
    const now = Date.now()
    const expiry = ttl ? now + ttl : now + defaultTTL
    
    // 如果缓存已满，删除最旧的项目
    if (cache.value.size >= maxSize) {
      const oldestKey = cache.value.keys().next().value
      cache.value.delete(oldestKey)
    }
    
    cache.value.set(key, {
      data: data as any,
      timestamp: now,
      expiry
    })
  }
  
  // 获取缓存
  const get = (key: string): T | null => {
    const item = cache.value.get(key)
    
    if (!item) {
      return null
    }
    
    const now = Date.now()
    
    // 检查是否过期
    if (item.expiry && now > item.expiry) {
      cache.value.delete(key)
      return null
    }
    
    return item.data as T
  }
  
  // 检查是否存在且未过期
  const has = (key: string): boolean => {
    return get(key) !== null
  }
  
  // 删除缓存
  const remove = (key: string): boolean => {
    return cache.value.delete(key)
  }
  
  // 清空缓存
  const clear = () => {
    cache.value.clear()
  }
  
  // 清理过期缓存
  const cleanup = () => {
    const now = Date.now()
    const keysToDelete: string[] = []
    
    cache.value.forEach((item, key) => {
      if (item.expiry && now > item.expiry) {
        keysToDelete.push(key)
      }
    })
    
    keysToDelete.forEach(key => cache.value.delete(key))
    
    return keysToDelete.length
  }
  
  // 获取缓存统计信息
  const stats = computed(() => ({
    size: cache.value.size,
    maxSize,
    usage: (cache.value.size / maxSize) * 100
  }))
  
  // 获取或设置缓存（如果不存在则执行获取函数）
  const getOrSet = async (
    key: string,
    fetchFn: () => Promise<T>,
    ttl?: number
  ): Promise<T> => {
    const cached = get(key)
    
    if (cached !== null) {
      return cached
    }
    
    const data = await fetchFn()
    set(key, data, ttl)
    
    return data
  }
  
  // 批量设置
  const setMany = (items: Array<{ key: string; data: T; ttl?: number }>) => {
    items.forEach(({ key, data, ttl }) => {
      set(key, data, ttl)
    })
  }
  
  // 批量获取
  const getMany = (keys: string[]): Array<{ key: string; data: T | null }> => {
    return keys.map(key => ({
      key,
      data: get(key)
    }))
  }
  
  return {
    set,
    get,
    has,
    remove,
    clear,
    cleanup,
    stats,
    getOrSet,
    setMany,
    getMany
  }
}

// 全局缓存实例
export const globalCache = useCache({
  maxSize: 500,
  defaultTTL: 10 * 60 * 1000 // 10分钟
})